home *** CD-ROM | disk | FTP | other *** search
/ Amiga Plus 2004 #11 / Amiga Plus CD - 2004 - No. 11.iso / AmiSoft / Misc / emu / fbzx.lha / fbzx / Z80.c < prev    next >
C/C++ Source or Header  |  2004-08-26  |  21KB  |  660 lines

  1. /** Z80: portable Z80 emulator *******************************/
  2. /**                                                         **/
  3. /**                           Z80.c                         **/
  4. /**                                                         **/
  5. /** This file contains implementation for Z80 CPU. Don't    **/
  6. /** forget to provide RdZ80(), WrZ80(), InZ80(), OutZ80(),  **/
  7. /** LoopZ80(), and PatchZ80() functions to accomodate the   **/
  8. /** emulated machine's architecture.                        **/
  9. /**                                                         **/
  10. /** Copyright (C) Marat Fayzullin 1994-2002                 **/
  11. /**     You are not allowed to distribute this software     **/
  12. /**     commercially. Please, notify me, if you make any    **/   
  13. /**     changes to this file.                               **/
  14. /*************************************************************/
  15.  
  16. #include "Z80.h"
  17. #include "Tables.h"
  18. #include <stdio.h>
  19.  
  20. static void CodesDD(register Z80 *);
  21. static void CodesFD(register Z80 *);
  22.  
  23. /** INLINE ***************************************************/
  24. /** Different compilers inline C functions differently.     **/
  25. /*************************************************************/
  26. #ifdef __GNUC__
  27. #define INLINE inline
  28. #else
  29. #define INLINE static
  30. #endif
  31.  
  32. /** System-Dependent Stuff ***********************************/
  33. /** This is system-dependent code put here to speed things  **/
  34. /** up. It has to stay inlined to be fast.                  **/
  35. /*************************************************************/
  36. #ifdef COLEM
  37. extern byte *RAM;
  38. INLINE byte RdZ80(word A) { return(RAM[A]); }
  39. #endif
  40. #ifdef MG
  41. extern byte *Page[];
  42. INLINE byte RdZ80(word A) { return(Page[A>>13][A&0x1FFF]); }
  43. #endif
  44. #ifdef FMSX
  45. extern byte *RAM[],PSL[],SSLReg;
  46. INLINE byte RdZ80(word A)
  47. {
  48.   if(A!=0xFFFF) return(RAM[A>>13][A&0x1FFF]);
  49.   else return((PSL[3]==3)? ~SSLReg:RAM[7][0x1FFF]);
  50. }
  51. #endif
  52.  
  53. #define S(Fl)        R->AF.B.l|=Fl
  54. #define R(Fl)        R->AF.B.l&=~(Fl)
  55. #define FLAGS(Rg,Fl) R->AF.B.l=Fl|ZSTable[Rg]
  56.  
  57. #define M_RLC(Rg)      R->AF.B.l=Rg>>7;Rg=(Rg<<1)|R->AF.B.l;R->AF.B.l|=PZSTable[Rg]
  58. #define M_RRC(Rg)      R->AF.B.l=Rg&0x01;Rg=(Rg>>1)|(R->AF.B.l<<7);R->AF.B.l|=PZSTable[Rg]
  59. #define M_RL(Rg)       \
  60.   if(Rg&0x80)          \
  61.   {                    \
  62.     Rg=(Rg<<1)|(R->AF.B.l&C_FLAG); \
  63.     R->AF.B.l=PZSTable[Rg]|C_FLAG; \
  64.   }                    \
  65.   else                 \
  66.   {                    \
  67.     Rg=(Rg<<1)|(R->AF.B.l&C_FLAG); \
  68.     R->AF.B.l=PZSTable[Rg];        \
  69.   }
  70. #define M_RR(Rg)       \
  71.   if(Rg&0x01)          \
  72.   {                    \
  73.     Rg=(Rg>>1)|(R->AF.B.l<<7);     \
  74.     R->AF.B.l=PZSTable[Rg]|C_FLAG; \
  75.   }                    \
  76.   else                 \
  77.   {                    \
  78.     Rg=(Rg>>1)|(R->AF.B.l<<7);     \
  79.     R->AF.B.l=PZSTable[Rg];        \
  80.   }
  81.   
  82. #define M_SLA(Rg)      \
  83.   R->AF.B.l=Rg>>7;Rg<<=1;R->AF.B.l|=PZSTable[Rg]
  84. #define M_SRA(Rg)      \
  85.   R->AF.B.l=Rg&C_FLAG;Rg=(Rg>>1)|(Rg&0x80);R->AF.B.l|=PZSTable[Rg]
  86.  
  87. #define M_SLL(Rg)      \
  88.   R->AF.B.l=Rg>>7;Rg=(Rg<<1)|0x01;R->AF.B.l|=PZSTable[Rg]
  89. #define M_SRL(Rg)      \
  90.   R->AF.B.l=Rg&0x01;Rg>>=1;R->AF.B.l|=PZSTable[Rg]
  91.  
  92. #define M_BIT(Bit,Rg)  \
  93.   R->AF.B.l=(R->AF.B.l&C_FLAG)|H_FLAG|PZSTable[Rg&(1<<Bit)]
  94.  
  95. #define M_SET(Bit,Rg) Rg|=1<<Bit
  96. #define M_RES(Bit,Rg) Rg&=~(1<<Bit)
  97.  
  98. #define M_POP(Rg)      \
  99.   R->Rg.B.l=RdZ80(R->SP.W++);R->Rg.B.h=RdZ80(R->SP.W++)
  100. #define M_PUSH(Rg)     \
  101.   WrZ80(--R->SP.W,R->Rg.B.h);WrZ80(--R->SP.W,R->Rg.B.l)
  102.  
  103. #define M_CALL         \
  104.   J.B.l=RdZ80(R->PC.W++);J.B.h=RdZ80(R->PC.W++);         \
  105.   WrZ80(--R->SP.W,R->PC.B.h);WrZ80(--R->SP.W,R->PC.B.l); \
  106.   R->PC.W=J.W
  107.  
  108. #define M_JP  J.B.l=RdZ80(R->PC.W++);J.B.h=RdZ80(R->PC.W);R->PC.W=J.W
  109. #define M_JR  R->PC.W+=(offset)RdZ80(R->PC.W)+1
  110. #define M_RET R->PC.B.l=RdZ80(R->SP.W++);R->PC.B.h=RdZ80(R->SP.W++)
  111.  
  112. #define M_RST(Ad)      \
  113.   WrZ80(--R->SP.W,R->PC.B.h);WrZ80(--R->SP.W,R->PC.B.l);R->PC.W=Ad
  114.  
  115. #define M_LDWORD(Rg)   \
  116.   R->Rg.B.l=RdZ80(R->PC.W++);R->Rg.B.h=RdZ80(R->PC.W++)
  117.  
  118. #define M_ADD(Rg)      \
  119.   J.W=R->AF.B.h+Rg;     \
  120.   R->AF.B.l=            \
  121.     (~(R->AF.B.h^Rg)&(Rg^J.B.l)&0x80? V_FLAG:0)| \
  122.     J.B.h|ZSTable[J.B.l]|                        \
  123.     ((R->AF.B.h^Rg^J.B.l)&H_FLAG);               \
  124.   R->AF.B.h=J.B.l       
  125.  
  126. #define M_SUB(Rg)      \
  127.   J.W=R->AF.B.h-Rg;    \
  128.   R->AF.B.l=           \
  129.     ((R->AF.B.h^Rg)&(R->AF.B.h^J.B.l)&0x80? V_FLAG:0)| \
  130.     N_FLAG|-J.B.h|ZSTable[J.B.l]|                      \
  131.     ((R->AF.B.h^Rg^J.B.l)&H_FLAG);                     \
  132.   R->AF.B.h=J.B.l
  133.  
  134. #define M_ADC(Rg)      \
  135.   J.W=R->AF.B.h+Rg+(R->AF.B.l&C_FLAG); \
  136.   R->AF.B.l=                           \
  137.     (~(R->AF.B.h^Rg)&(Rg^J.B.l)&0x80? V_FLAG:0)| \
  138.     J.B.h|ZSTable[J.B.l]|              \
  139.     ((R->AF.B.h^Rg^J.B.l)&H_FLAG);     \
  140.   R->AF.B.h=J.B.l
  141.  
  142. #define M_SBC(Rg)      \
  143.   J.W=R->AF.B.h-Rg-(R->AF.B.l&C_FLAG); \
  144.   R->AF.B.l=                           \
  145.     ((R->AF.B.h^Rg)&(R->AF.B.h^J.B.l)&0x80? V_FLAG:0)| \
  146.     N_FLAG|-J.B.h|ZSTable[J.B.l]|      \
  147.     ((R->AF.B.h^Rg^J.B.l)&H_FLAG);     \
  148.   R->AF.B.h=J.B.l
  149.  
  150. #define M_CP(Rg)       \
  151.   J.W=R->AF.B.h-Rg;    \
  152.   R->AF.B.l=           \
  153.     ((R->AF.B.h^Rg)&(R->AF.B.h^J.B.l)&0x80? V_FLAG:0)| \
  154.     N_FLAG|-J.B.h|ZSTable[J.B.l]|                      \
  155.     ((R->AF.B.h^Rg^J.B.l)&H_FLAG)
  156.  
  157. #define M_AND(Rg) R->AF.B.h&=Rg;R->AF.B.l=H_FLAG|PZSTable[R->AF.B.h]
  158. #define M_OR(Rg)  R->AF.B.h|=Rg;R->AF.B.l=PZSTable[R->AF.B.h]
  159. #define M_XOR(Rg) R->AF.B.h^=Rg;R->AF.B.l=PZSTable[R->AF.B.h]
  160.  
  161. #define M_IN(Rg)        \
  162.   Rg=InZ80(((word)(R->BC.B.l))+256*((word)R->BC.B.h));  \
  163.   R->AF.B.l=PZSTable[Rg]|(R->AF.B.l&C_FLAG)
  164.  
  165. #define M_INC(Rg)       \
  166.   Rg++;                 \
  167.   R->AF.B.l=            \
  168.     (R->AF.B.l&C_FLAG)|ZSTable[Rg]|           \
  169.     (Rg==0x80? V_FLAG:0)|(Rg&0x0F? 0:H_FLAG)
  170.  
  171. #define M_DEC(Rg)       \
  172.   Rg--;                 \
  173.   R->AF.B.l=            \
  174.     N_FLAG|(R->AF.B.l&C_FLAG)|ZSTable[Rg]| \
  175.     (Rg==0x7F? V_FLAG:0)|((Rg&0x0F)==0x0F? H_FLAG:0)
  176.  
  177. #define M_ADDW(Rg1,Rg2) \
  178.   J.W=(R->Rg1.W+R->Rg2.W)&0xFFFF;                        \
  179.   R->AF.B.l=                                             \
  180.     (R->AF.B.l&~(H_FLAG|N_FLAG|C_FLAG))|                 \
  181.     ((R->Rg1.W^R->Rg2.W^J.W)&0x1000? H_FLAG:0)|          \
  182.     (((long)R->Rg1.W+(long)R->Rg2.W)&0x10000? C_FLAG:0); \
  183.   R->Rg1.W=J.W
  184.  
  185. #define M_ADCW(Rg)      \
  186.   I=R->AF.B.l&C_FLAG;J.W=(R->HL.W+R->Rg.W+I)&0xFFFF;           \
  187.   R->AF.B.l=                                                   \
  188.     (((long)R->HL.W+(long)R->Rg.W+(long)I)&0x10000? C_FLAG:0)| \
  189.     (~(R->HL.W^R->Rg.W)&(R->Rg.W^J.W)&0x8000? V_FLAG:0)|       \
  190.     ((R->HL.W^R->Rg.W^J.W)&0x1000? H_FLAG:0)|                  \
  191.     (J.W? 0:Z_FLAG)|(J.B.h&S_FLAG);                            \
  192.   R->HL.W=J.W
  193.    
  194. #define M_SBCW(Rg)      \
  195.   I=R->AF.B.l&C_FLAG;J.W=(R->HL.W-R->Rg.W-I)&0xFFFF;           \
  196.   R->AF.B.l=                                                   \
  197.     N_FLAG|                                                    \
  198.     (((long)R->HL.W-(long)R->Rg.W-(long)I)&0x10000? C_FLAG:0)| \
  199.     ((R->HL.W^R->Rg.W)&(R->HL.W^J.W)&0x8000? V_FLAG:0)|        \
  200.     ((R->HL.W^R->Rg.W^J.W)&0x1000? H_FLAG:0)|                  \
  201.     (J.W? 0:Z_FLAG)|(J.B.h&S_FLAG);                            \
  202.   R->HL.W=J.W
  203.  
  204. enum Codes
  205. {
  206.   NOP,LD_BC_WORD,LD_xBC_A,INC_BC,INC_B,DEC_B,LD_B_BYTE,RLCA,
  207.   EX_AF_AF,ADD_HL_BC,LD_A_xBC,DEC_BC,INC_C,DEC_C,LD_C_BYTE,RRCA,
  208.   DJNZ,LD_DE_WORD,LD_xDE_A,INC_DE,INC_D,DEC_D,LD_D_BYTE,RLA,
  209.   JR,ADD_HL_DE,LD_A_xDE,DEC_DE,INC_E,DEC_E,LD_E_BYTE,RRA,
  210.   JR_NZ,LD_HL_WORD,LD_xWORD_HL,INC_HL,INC_H,DEC_H,LD_H_BYTE,DAA,
  211.   JR_Z,ADD_HL_HL,LD_HL_xWORD,DEC_HL,INC_L,DEC_L,LD_L_BYTE,CPL,
  212.   JR_NC,LD_SP_WORD,LD_xWORD_A,INC_SP,INC_xHL,DEC_xHL,LD_xHL_BYTE,SCF,
  213.   JR_C,ADD_HL_SP,LD_A_xWORD,DEC_SP,INC_A,DEC_A,LD_A_BYTE,CCF,
  214.   LD_B_B,LD_B_C,LD_B_D,LD_B_E,LD_B_H,LD_B_L,LD_B_xHL,LD_B_A,
  215.   LD_C_B,LD_C_C,LD_C_D,LD_C_E,LD_C_H,LD_C_L,LD_C_xHL,LD_C_A,
  216.   LD_D_B,LD_D_C,LD_D_D,LD_D_E,LD_D_H,LD_D_L,LD_D_xHL,LD_D_A,
  217.   LD_E_B,LD_E_C,LD_E_D,LD_E_E,LD_E_H,LD_E_L,LD_E_xHL,LD_E_A,
  218.   LD_H_B,LD_H_C,LD_H_D,LD_H_E,LD_H_H,LD_H_L,LD_H_xHL,LD_H_A,
  219.   LD_L_B,LD_L_C,LD_L_D,LD_L_E,LD_L_H,LD_L_L,LD_L_xHL,LD_L_A,
  220.   LD_xHL_B,LD_xHL_C,LD_xHL_D,LD_xHL_E,LD_xHL_H,LD_xHL_L,HALT,LD_xHL_A,
  221.   LD_A_B,LD_A_C,LD_A_D,LD_A_E,LD_A_H,LD_A_L,LD_A_xHL,LD_A_A,
  222.   ADD_B,ADD_C,ADD_D,ADD_E,ADD_H,ADD_L,ADD_xHL,ADD_A,
  223.   ADC_B,ADC_C,ADC_D,ADC_E,ADC_H,ADC_L,ADC_xHL,ADC_A,
  224.   SUB_B,SUB_C,SUB_D,SUB_E,SUB_H,SUB_L,SUB_xHL,SUB_A,
  225.   SBC_B,SBC_C,SBC_D,SBC_E,SBC_H,SBC_L,SBC_xHL,SBC_A,
  226.   AND_B,AND_C,AND_D,AND_E,AND_H,AND_L,AND_xHL,AND_A,
  227.   XOR_B,XOR_C,XOR_D,XOR_E,XOR_H,XOR_L,XOR_xHL,XOR_A,
  228.   OR_B,OR_C,OR_D,OR_E,OR_H,OR_L,OR_xHL,OR_A,
  229.   CP_B,CP_C,CP_D,CP_E,CP_H,CP_L,CP_xHL,CP_A,
  230.   RET_NZ,POP_BC,JP_NZ,JP,CALL_NZ,PUSH_BC,ADD_BYTE,RST00,
  231.   RET_Z,RET,JP_Z,PFX_CB,CALL_Z,CALL,ADC_BYTE,RST08,
  232.   RET_NC,POP_DE,JP_NC,OUTA,CALL_NC,PUSH_DE,SUB_BYTE,RST10,
  233.   RET_C,EXX,JP_C,INA,CALL_C,PFX_DD,SBC_BYTE,RST18,
  234.   RET_PO,POP_HL,JP_PO,EX_HL_xSP,CALL_PO,PUSH_HL,AND_BYTE,RST20,
  235.   RET_PE,LD_PC_HL,JP_PE,EX_DE_HL,CALL_PE,PFX_ED,XOR_BYTE,RST28,
  236.   RET_P,POP_AF,JP_P,DI,CALL_P,PUSH_AF,OR_BYTE,RST30,
  237.   RET_M,LD_SP_HL,JP_M,EI,CALL_M,PFX_FD,CP_BYTE,RST38
  238. };
  239.  
  240. enum CodesCB
  241. {
  242.   RLC_B,RLC_C,RLC_D,RLC_E,RLC_H,RLC_L,RLC_xHL,RLC_A,
  243.   RRC_B,RRC_C,RRC_D,RRC_E,RRC_H,RRC_L,RRC_xHL,RRC_A,
  244.   RL_B,RL_C,RL_D,RL_E,RL_H,RL_L,RL_xHL,RL_A,
  245.   RR_B,RR_C,RR_D,RR_E,RR_H,RR_L,RR_xHL,RR_A,
  246.   SLA_B,SLA_C,SLA_D,SLA_E,SLA_H,SLA_L,SLA_xHL,SLA_A,
  247.   SRA_B,SRA_C,SRA_D,SRA_E,SRA_H,SRA_L,SRA_xHL,SRA_A,
  248.   SLL_B,SLL_C,SLL_D,SLL_E,SLL_H,SLL_L,SLL_xHL,SLL_A,
  249.   SRL_B,SRL_C,SRL_D,SRL_E,SRL_H,SRL_L,SRL_xHL,SRL_A,
  250.   BIT0_B,BIT0_C,BIT0_D,BIT0_E,BIT0_H,BIT0_L,BIT0_xHL,BIT0_A,
  251.   BIT1_B,BIT1_C,BIT1_D,BIT1_E,BIT1_H,BIT1_L,BIT1_xHL,BIT1_A,
  252.   BIT2_B,BIT2_C,BIT2_D,BIT2_E,BIT2_H,BIT2_L,BIT2_xHL,BIT2_A,
  253.   BIT3_B,BIT3_C,BIT3_D,BIT3_E,BIT3_H,BIT3_L,BIT3_xHL,BIT3_A,
  254.   BIT4_B,BIT4_C,BIT4_D,BIT4_E,BIT4_H,BIT4_L,BIT4_xHL,BIT4_A,
  255.   BIT5_B,BIT5_C,BIT5_D,BIT5_E,BIT5_H,BIT5_L,BIT5_xHL,BIT5_A,
  256.   BIT6_B,BIT6_C,BIT6_D,BIT6_E,BIT6_H,BIT6_L,BIT6_xHL,BIT6_A,
  257.   BIT7_B,BIT7_C,BIT7_D,BIT7_E,BIT7_H,BIT7_L,BIT7_xHL,BIT7_A,
  258.   RES0_B,RES0_C,RES0_D,RES0_E,RES0_H,RES0_L,RES0_xHL,RES0_A,
  259.   RES1_B,RES1_C,RES1_D,RES1_E,RES1_H,RES1_L,RES1_xHL,RES1_A,
  260.   RES2_B,RES2_C,RES2_D,RES2_E,RES2_H,RES2_L,RES2_xHL,RES2_A,
  261.   RES3_B,RES3_C,RES3_D,RES3_E,RES3_H,RES3_L,RES3_xHL,RES3_A,
  262.   RES4_B,RES4_C,RES4_D,RES4_E,RES4_H,RES4_L,RES4_xHL,RES4_A,
  263.   RES5_B,RES5_C,RES5_D,RES5_E,RES5_H,RES5_L,RES5_xHL,RES5_A,
  264.   RES6_B,RES6_C,RES6_D,RES6_E,RES6_H,RES6_L,RES6_xHL,RES6_A,
  265.   RES7_B,RES7_C,RES7_D,RES7_E,RES7_H,RES7_L,RES7_xHL,RES7_A,  
  266.   SET0_B,SET0_C,SET0_D,SET0_E,SET0_H,SET0_L,SET0_xHL,SET0_A,
  267.   SET1_B,SET1_C,SET1_D,SET1_E,SET1_H,SET1_L,SET1_xHL,SET1_A,
  268.   SET2_B,SET2_C,SET2_D,SET2_E,SET2_H,SET2_L,SET2_xHL,SET2_A,
  269.   SET3_B,SET3_C,SET3_D,SET3_E,SET3_H,SET3_L,SET3_xHL,SET3_A,
  270.   SET4_B,SET4_C,SET4_D,SET4_E,SET4_H,SET4_L,SET4_xHL,SET4_A,
  271.   SET5_B,SET5_C,SET5_D,SET5_E,SET5_H,SET5_L,SET5_xHL,SET5_A,
  272.   SET6_B,SET6_C,SET6_D,SET6_E,SET6_H,SET6_L,SET6_xHL,SET6_A,
  273.   SET7_B,SET7_C,SET7_D,SET7_E,SET7_H,SET7_L,SET7_xHL,SET7_A
  274. };
  275.   
  276. enum CodesED
  277. {
  278.   DB_00,DB_01,DB_02,DB_03,DB_04,DB_05,DB_06,DB_07,
  279.   DB_08,DB_09,DB_0A,DB_0B,DB_0C,DB_0D,DB_0E,DB_0F,
  280.   DB_10,DB_11,DB_12,DB_13,DB_14,DB_15,DB_16,DB_17,
  281.   DB_18,DB_19,DB_1A,DB_1B,DB_1C,DB_1D,DB_1E,DB_1F,
  282.   DB_20,DB_21,DB_22,DB_23,DB_24,DB_25,DB_26,DB_27,
  283.   DB_28,DB_29,DB_2A,DB_2B,DB_2C,DB_2D,DB_2E,DB_2F,
  284.   DB_30,DB_31,DB_32,DB_33,DB_34,DB_35,DB_36,DB_37,
  285.   DB_38,DB_39,DB_3A,DB_3B,DB_3C,DB_3D,DB_3E,DB_3F,
  286.   IN_B_xC,OUT_xC_B,SBC_HL_BC,LD_xWORDe_BC,NEG,RETN,IM_0,LD_I_A,
  287.   IN_C_xC,OUT_xC_C,ADC_HL_BC,LD_BC_xWORDe,DB_4C,RETI,DB_,LD_R_A,
  288.   IN_D_xC,OUT_xC_D,SBC_HL_DE,LD_xWORDe_DE,DB_54,DB_55,IM_1,LD_A_I,
  289.   IN_E_xC,OUT_xC_E,ADC_HL_DE,LD_DE_xWORDe,DB_5C,DB_5D,IM_2,LD_A_R,
  290.   IN_H_xC,OUT_xC_H,SBC_HL_HL,LD_xWORDe_HL,DB_64,DB_65,DB_66,RRD,
  291.   IN_L_xC,OUT_xC_L,ADC_HL_HL,LD_HL_xWORDe,DB_6C,DB_6D,DB_6E,RLD,
  292.   IN_F_xC,DB_71,SBC_HL_SP,LD_xWORDe_SP,DB_74,DB_75,DB_76,DB_77,
  293.   IN_A_xC,OUT_xC_A,ADC_HL_SP,LD_SP_xWORDe,DB_7C,DB_7D,DB_7E,DB_7F,
  294.   DB_80,DB_81,DB_82,DB_83,DB_84,DB_85,DB_86,DB_87,
  295.   DB_88,DB_89,DB_8A,DB_8B,DB_8C,DB_8D,DB_8E,DB_8F,
  296.   DB_90,DB_91,DB_92,DB_93,DB_94,DB_95,DB_96,DB_97,
  297.   DB_98,DB_99,DB_9A,DB_9B,DB_9C,DB_9D,DB_9E,DB_9F,
  298.   LDI,CPI,INI,OUTI,DB_A4,DB_A5,DB_A6,DB_A7,
  299.   LDD,CPD,IND,OUTD,DB_AC,DB_AD,DB_AE,DB_AF,
  300.   LDIR,CPIR,INIR,OTIR,DB_B4,DB_B5,DB_B6,DB_B7,
  301.   LDDR,CPDR,INDR,OTDR,DB_BC,DB_BD,DB_BE,DB_BF,
  302.   DB_C0,DB_C1,DB_C2,DB_C3,DB_C4,DB_C5,DB_C6,DB_C7,
  303.   DB_C8,DB_C9,DB_CA,DB_CB,DB_CC,DB_CD,DB_CE,DB_CF,
  304.   DB_D0,DB_D1,DB_D2,DB_D3,DB_D4,DB_D5,DB_D6,DB_D7,
  305.   DB_D8,DB_D9,DB_DA,DB_DB,DB_DC,DB_DD,DB_DE,DB_DF,
  306.   DB_E0,DB_E1,DB_E2,DB_E3,DB_E4,DB_E5,DB_E6,DB_E7,
  307.   DB_E8,DB_E9,DB_EA,DB_EB,DB_EC,DB_ED,DB_EE,DB_EF,
  308.   DB_F0,DB_F1,DB_F2,DB_F3,DB_F4,DB_F5,DB_F6,DB_F7,
  309.   DB_F8,DB_F9,DB_FA,DB_FB,DB_FC,DB_FD,DB_FE,DB_FF
  310. };
  311.  
  312. static void CodesCB(register Z80 *R)
  313. {
  314.   register byte I;
  315.  
  316.   I=RdZ80(R->PC.W++);
  317.   R->ICount-=CyclesCB[I];
  318.   R->TStates+=CyclesCB[I];  
  319.   switch(I)
  320.   {
  321. #include "CodesCB.h"
  322.     default:
  323.       if(R->TrapBadOps)
  324.         printf
  325.         (   
  326.           "[Z80 %lX] Unrecognized instruction: CB %02X at PC=%04X\n",
  327.           (long)(R->User),RdZ80(R->PC.W-1),R->PC.W-2
  328.         );
  329.   }
  330. }
  331.  
  332. static void CodesDDCB(register Z80 *R)
  333. {
  334.   register pair J;
  335.   register byte I;
  336.  
  337. #define XX IX    
  338.   J.W=R->XX.W+(offset)RdZ80(R->PC.W++);
  339.   I=RdZ80(R->PC.W++);
  340.   R->ICount-=CyclesXXCB[I];
  341.   R->TStates+=CyclesXXCB[I];
  342.   switch(I)
  343.   {
  344. #include "CodesXCB.h"
  345.     default:
  346.       if(R->TrapBadOps)
  347.         printf
  348.         (
  349.           "[Z80 %lX] Unrecognized instruction: DD CB %02X %02X at PC=%04X\n",
  350.           (long)(R->User),RdZ80(R->PC.W-2),RdZ80(R->PC.W-1),R->PC.W-4
  351.         );
  352.   }
  353. #undef XX
  354. }
  355.  
  356. static void CodesFDCB(register Z80 *R)
  357. {
  358.   register pair J;
  359.   register byte I;
  360.  
  361. #define XX IY
  362.   J.W=R->XX.W+(offset)RdZ80(R->PC.W++);
  363.   I=RdZ80(R->PC.W++);
  364.   R->ICount-=CyclesXXCB[I];
  365.   R->TStates+=CyclesXXCB[I];
  366.   switch(I)
  367.   {
  368. #include "CodesXCB.h"
  369.     default:
  370.       if(R->TrapBadOps)
  371.         printf
  372.         (
  373.           "[Z80 %lX] Unrecognized instruction: FD CB %02X %02X at PC=%04X\n",
  374.           (long)R->User,RdZ80(R->PC.W-2),RdZ80(R->PC.W-1),R->PC.W-4
  375.         );
  376.   }
  377. #undef XX
  378. }
  379.  
  380. static void CodesED(register Z80 *R)
  381. {
  382.   register byte I;
  383.   register pair J;
  384.  
  385.   I=RdZ80(R->PC.W++);
  386.   R->ICount-=CyclesED[I];
  387.   R->TStates+=CyclesED[I];
  388.   switch(I)
  389.   {
  390. #include "CodesED.h"
  391.     case PFX_ED:
  392.      R->PC.W--;R->R--;break;
  393.     default:
  394.       if(R->TrapBadOps)
  395.         printf
  396.         (
  397.           "[Z80 %lX] Unrecognized instruction: ED %02X at PC=%04X\n",
  398.           (long)R->User,RdZ80(R->PC.W-1),R->PC.W-2
  399.         );
  400.   }
  401. }
  402.  
  403. static void CodesDD(register Z80 *R)
  404. {
  405.   register byte I;
  406.   register pair J;
  407.  
  408. #define XX IX
  409.   I=RdZ80(R->PC.W++);
  410.   R->ICount-=CyclesXX[I];
  411.   R->TStates+=CyclesXX[I];
  412.   switch(I)
  413.   {
  414. #include "CodesXX.h"
  415.     case PFX_FD:
  416.       R->R--;
  417.       R->PC.W--;
  418.       printf("FD dentro de DD\n");
  419.     break;
  420.     case PFX_DD:
  421.       R->R--;
  422.       R->PC.W--;
  423.       printf("DD dentro de DD\n");
  424.       break;      
  425.     case PFX_CB:
  426.       CodesDDCB(R);break;
  427.     default:
  428.       if(R->TrapBadOps)
  429.         printf
  430.         (
  431.           "[Z80 %lX] Unrecognized instruction: DD %02X at PC=%04X\n",
  432.           (long)R->User,RdZ80(R->PC.W-1),R->PC.W-2
  433.         );
  434.   }
  435. #undef XX
  436. }
  437.  
  438. static void CodesFD(register Z80 *R)
  439. {
  440.   register byte I;
  441.   register pair J;
  442.  
  443. #define XX IY
  444.   I=RdZ80(R->PC.W++);
  445.   R->ICount-=CyclesXX[I];
  446.   R->TStates+=CyclesXX[I];
  447.   switch(I)
  448.   {
  449. #include "CodesXX.h"
  450.     case PFX_FD:
  451.       R->R--;
  452.      R->PC.W--;
  453.         printf("FD dentro de FD\n");
  454.     break;
  455.     case PFX_DD:
  456.       R->R--;
  457.       R->PC.W--;      
  458.       printf("DD dentro de FD\n");
  459.       break;
  460.     case PFX_CB:
  461.       CodesFDCB(R);break;
  462.     default:
  463.         printf
  464.         (
  465.           "Unrecognized instruction: FD %02X at PC=%04X\n",
  466.           RdZ80(R->PC.W-1),R->PC.W-2
  467.         );
  468.   }
  469. #undef XX
  470. }
  471.  
  472. /** ResetZ80() ***********************************************/
  473. /** This function can be used to reset the register struct  **/
  474. /** before starting execution with Z80(). It sets the       **/
  475. /** registers to their supposed initial values.             **/
  476. /*************************************************************/
  477. void ResetZ80(Z80 *R)
  478. {
  479.   R->R           = 0x0000;
  480.   R->R2            = 0x0000;
  481.   R->PC.W     = 0x0000;
  482.   R->SP.W     = 0xF000;
  483.   R->AF.W     = 0x0000;
  484.   R->BC.W     = 0x0000;
  485.   R->DE.W     = 0x0000;
  486.   R->HL.W     = 0x0000;
  487.   R->AF1.W    = 0x0000;
  488.   R->BC1.W    = 0x0000;
  489.   R->DE1.W    = 0x0000;
  490.   R->HL1.W    = 0x0000;
  491.   R->IX.W     = 0x0000;
  492.   R->IY.W     = 0x0000;
  493.   R->I        = 0x00;
  494.   R->IFF      = 0x00;
  495.   R->ICount   = R->IPeriod;
  496.   R->IRequest = INT_NONE;
  497. }
  498.  
  499. /** ExecZ80() ************************************************/
  500. /** This function will execute a single Z80 opcode. It will **/
  501. /** then return next PC, and current register values in R.  **/
  502. /*************************************************************/
  503. word ExecZ80(Z80 *R)
  504. {
  505.   register byte I;
  506.   register pair J;
  507.  
  508.   I=RdZ80(R->PC.W++);
  509.   R->ICount-=Cycles[I];
  510.   R->TStates+=Cycles[I];
  511.   R->R++;
  512.   switch(I)
  513.   {
  514. #include "Codes.h"
  515.     case PFX_CB: R->R++; CodesCB(R);break;
  516.     case PFX_ED: R->R++; CodesED(R);break;
  517.     case PFX_FD: R->R++; CodesFD(R);break;
  518.     case PFX_DD: R->R++; CodesDD(R);break;
  519.   }
  520.  
  521.   /* We are done */
  522.   return(R->PC.W);
  523. }
  524.  
  525. /** IntZ80() *************************************************/
  526. /** This function will generate interrupt of given vector.  **/
  527. /*************************************************************/
  528. void IntZ80(Z80 *R,word Vector)
  529. {
  530.   if((R->IFF&IFF_1)||(Vector==INT_NMI))
  531.   {
  532.       R->R++;
  533.     /* If HALTed, take CPU off HALT instruction */
  534.     if(R->IFF&IFF_HALT) { R->PC.W++;R->IFF&=~IFF_HALT; }
  535.  
  536.     /* Save PC on stack */
  537.     M_PUSH(PC);
  538.  
  539.     /* Automatically reset IRequest if needed */
  540.     if(R->IAutoReset&&(Vector==R->IRequest)) R->IRequest=INT_NONE;
  541.  
  542.     /* If it is NMI... */
  543.     if(Vector==INT_NMI)
  544.     {
  545.       R->TStates+=11; // we need 11 tstates to reach 0x0066
  546.       /* Copy IFF1 to IFF2 */
  547.       if(R->IFF&IFF_1) R->IFF|=IFF_2; else R->IFF&=~IFF_2;
  548.       /* Clear IFF1 */
  549.       R->IFF&=~(IFF_1|IFF_EI);
  550.       /* Jump to hardwired NMI vector */
  551.       R->PC.W=0x0066;
  552.       /* Done */
  553.       return;
  554.     }
  555.  
  556.     /* Further interrupts off */
  557.     R->IFF&=~(IFF_1|IFF_2|IFF_EI);
  558.  
  559.     /* If in IM2 mode... */
  560.     if(R->IFF&IFF_IM2)
  561.     {
  562.       R->TStates+=19; // we need 19 tstates to reach the INT sub-routine
  563.       /* Make up the vector address */
  564.       Vector=(Vector&0xFF)|((word)(R->I)<<8);
  565.       /* Read the vector */
  566.       R->PC.B.l=RdZ80(Vector++);
  567.       R->PC.B.h=RdZ80(Vector);
  568.       /* Done */
  569.       return;
  570.     }
  571.  
  572.     /* If in IM1 mode, just jump to hardwired IRQ vector */
  573.     if(R->IFF&IFF_IM1) { R->TStates+=13;R->PC.W=0x0038;return; }
  574.  
  575.     /* If in IM0 mode... */
  576.  
  577.     R->TStates+=13; // we need 13 tstates to run a RST# in IM0
  578.  
  579.     /* Jump to a vector */
  580.     switch(Vector)
  581.     {
  582.       case INT_RST00: R->PC.W=0x0000;break;
  583.       case INT_RST08: R->PC.W=0x0008;break;
  584.       case INT_RST10: R->PC.W=0x0010;break;
  585.       case INT_RST18: R->PC.W=0x0018;break;
  586.       case INT_RST20: R->PC.W=0x0020;break;
  587.       case INT_RST28: R->PC.W=0x0028;break;
  588.       case INT_RST30: R->PC.W=0x0030;break;
  589.       case INT_RST38: R->PC.W=0x0038;break;
  590.     }
  591.   }
  592. }
  593.  
  594. /** RunZ80() *************************************************/
  595. /** This function will run Z80 code until an LoopZ80() call **/
  596. /** returns INT_QUIT. It will return the PC at which        **/
  597. /** emulation stopped, and current register values in R.    **/
  598. /*************************************************************/
  599. word RunZ80(Z80 *R)
  600. {
  601.   register byte I;
  602.   register pair J;
  603.  
  604.   for(;;)
  605.   {
  606. #ifdef DEBUG
  607.     /* Turn tracing on when reached trap address */
  608.     if(R->PC.W==R->Trap) R->Trace=1;
  609.     /* Call single-step debugger, exit if requested */
  610.     if(R->Trace)
  611.       if(!DebugZ80(R)) return(R->PC.W);
  612. #endif
  613.  
  614.     I=RdZ80(R->PC.W++);
  615.     R->ICount-=Cycles[I];
  616.     R->TStates+=Cycles[I];
  617.     switch(I)
  618.     {
  619. #include "Codes.h"
  620.       case PFX_CB: CodesCB(R);break;
  621.       case PFX_ED: CodesED(R);break;
  622.       case PFX_FD: CodesFD(R);break;
  623.       case PFX_DD: CodesDD(R);break;
  624.     }
  625.  
  626.     /* If cycle counter expired... */
  627.     if(R->ICount<=0)
  628.     {
  629.       /* If we have come after EI, get address from IRequest */
  630.       /* Otherwise, get it from the loop handler             */
  631.       if(R->IFF&IFF_EI)
  632.       {
  633.         R->IFF=(R->IFF&~IFF_EI)|IFF_1; /* Done with AfterEI state */
  634.         R->ICount+=R->IBackup-1;       /* Restore the ICount      */
  635.  
  636.         /* Call periodic handler or set pending IRQ */
  637.         if(R->ICount>0) J.W=R->IRequest;
  638.         else
  639.         {
  640.           J.W=LoopZ80(R);        /* Call periodic handler    */
  641.           R->ICount+=R->IPeriod; /* Reset the cycle counter  */
  642.           if(J.W==INT_NONE) J.W=R->IRequest;  /* Pending IRQ */
  643.         }
  644.       }
  645.       else
  646.       {
  647.         J.W=LoopZ80(R);          /* Call periodic handler    */
  648.         R->ICount+=R->IPeriod;   /* Reset the cycle counter  */
  649.         if(J.W==INT_NONE) J.W=R->IRequest;    /* Pending IRQ */
  650.       }
  651.  
  652.       if(J.W==INT_QUIT) return(R->PC.W); /* Exit if INT_QUIT */
  653.       if(J.W!=INT_NONE) IntZ80(R,J.W);   /* Int-pt if needed */
  654.     }
  655.   }
  656.  
  657.   /* Execution stopped */
  658.   return(R->PC.W);
  659. }
  660.